package com.aruba.bulethoothdemoapplication.utils.printer;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * Description:
 * Created by lpc on 2017/3/27.
 */
public class BitmapUtils {

    // nWidth必须为8的倍数,这个只需在上层控制即可
    // 之所以弄成一维数组，是因为一维数组速度会快一点
    private static int[] p0 = { 0, 0x80 };
    private static int[] p1 = { 0, 0x40 };
    private static int[] p2 = { 0, 0x20 };
    private static int[] p3 = { 0, 0x10 };
    private static int[] p4 = { 0, 0x08 };
    private static int[] p5 = { 0, 0x04 };
    private static int[] p6 = { 0, 0x02 };

    //
    public static void format_K_threshold(int[] orgpixels, int xsize,
                                          int ysize, byte[] despixels) {

        int graytotal = 0;
        int grayave = 168;
        int i, j;
        int gray;

        int k = 0;
        for (i = 0; i < ysize; i++) {

            for (j = 0; j < xsize; j++) {

                gray = orgpixels[k] & 0xff;
                graytotal += gray;
                k++;
            }
        }
//        grayave = graytotal / ysize / xsize;
//        Log.e("grayave=",grayave+"");

        // 二值化
        k = 0;
        for (i = 0; i < ysize; i++) {

            for (j = 0; j < xsize; j++) {

                gray = orgpixels[k] & 0xff;

                if (gray > grayave)
                    despixels[k] = 0;// white
                else
                    despixels[k] = 1;

                k++;
            }
        }
    }

    // 缩放，暂时需要public以便调试，完成之后不用这个。
    public static Bitmap resizeImage(Bitmap bitmap, int w, int h) {

        // load the origial Bitmap
        Bitmap BitmapOrg = bitmap;

        int width = BitmapOrg.getWidth();
        int height = BitmapOrg.getHeight();
        int newWidth = w;
        int newHeight = h;

        // calculate the scale
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;

        // create a matrix for the manipulation
        Matrix matrix = new Matrix();
        // resize the Bitmap
        matrix.postScale(scaleWidth, scaleHeight);
        // if you want to rotate the Bitmap
        // matrix.postRotate(45);

        // recreate the new Bitmap
        Bitmap resizedBitmap = Bitmap.createBitmap(BitmapOrg, 0, 0, width,
                height, matrix, true);

        // make a Drawable from Bitmap to allow to set the Bitmap
        // to the ImageView, ImageButton or what ever
        return resizedBitmap;
    }

    // 转成灰度图
    public static Bitmap toGrayscale(Bitmap bmpOriginal) {
        int width, height;
        height = bmpOriginal.getHeight();
        width = bmpOriginal.getWidth();
        Bitmap bmpGrayscale = Bitmap.createBitmap(width, height,
                Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bmpGrayscale);
        Paint paint = new Paint();
        ColorMatrix cm = new ColorMatrix();
        cm.setSaturation(1);     //设置颜色矩阵的饱和度，0为灰色，1为原图
        ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
        paint.setColorFilter(f);
        c.drawBitmap(bmpOriginal, 0, 0, paint);
        return bmpGrayscale;
    }

    /**
     * 将ARGB图转化为二值图，0代表黑，1代表白
     * */
    public static byte[] bitmapToBWPix(Bitmap bitmap){
        int mWidth = bitmap.getWidth();
        int mHeight = bitmap.getHeight();

        int[] pixels = new int[mWidth * mHeight];
        byte[] data = new byte[mWidth * mHeight];

        bitmap.getPixels(pixels, 0, mWidth, 0, 0,
                mWidth, mHeight);

//        format_K_dither16x16(pixels,bitmap.getWidth(), bitmap.getHeight(), data);
//        format_K_threshold(bitmap);
        format_K_threshold(pixels,bitmap.getWidth(), bitmap.getHeight(), data);
//        format_K_dither8x8(pixels,bitmap.getWidth(), bitmap.getHeight(), data);
        return data;
    }

    private static byte[] eachLinePixToCmd(byte[] src, int nWidth, int nMode) {
        int nHeight = src.length / nWidth;
        int nBytesPerLine = nWidth / 8;
        byte[] data = new byte[nHeight * (8 + nBytesPerLine)];
        int offset;
        int k = 0;
        for (int i = 0; i < nHeight; i++) {
            offset = i * (8 + nBytesPerLine);
            data[offset + 0] = 0x1d;
            data[offset + 1] = 0x76;
            data[offset + 2] = 0x30;
            data[offset + 3] = (byte) (nMode & 0x01);
            data[offset + 4] = (byte) (nBytesPerLine % 0x100);
            data[offset + 5] = (byte) (nBytesPerLine / 0x100);
            data[offset + 6] = 0x01;
            data[offset + 7] = 0x00;
            for (int j = 0; j < nBytesPerLine; j++) {
                data[offset + 8 + j] = (byte) (p0[src[k]] + p1[src[k + 1]]
                        + p2[src[k + 2]] + p3[src[k + 3]] + p4[src[k + 4]]
                        + p5[src[k + 5]] + p6[src[k + 6]] + src[k + 7]);
                k = k + 8;
            }
        }

        return data;
    }

    public static byte[] bitmapToByte(Bitmap mBitmap, int nWidth, int nMode){

        Log.e("lpc", "图片宽度：" + nWidth);
        // 先转黑白，再调用函数缩放位图
        // 不转黑白
        int width = ((nWidth + 7) / 8) * 8;
        int height = mBitmap.getHeight() * width / mBitmap.getWidth();
        height = ((height + 7) / 8) * 8;
        Bitmap rszBitmap = resizeImage(mBitmap, width, height);
//        Bitmap grayBitmap = toGrayscale(rszBitmap);
        byte[] dithered = bitmapToBWPix(rszBitmap);

        byte[] data = eachLinePixToCmd(dithered, nWidth, nMode);

        return data;
    }
    public static void saveBitmap(String path, Bitmap mBitmap){
        File f = new File(path);
        try {
            f.createNewFile();
        } catch (IOException e) {
            // TODO Auto-generated catch block
//            DebugMessage.put("在保存图片时出错："+e.toString());
        }
        FileOutputStream fOut = null;
        try {
            fOut = new FileOutputStream(f);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        mBitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
        try {
            fOut.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            fOut.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
//图片压缩
    public static Bitmap getBitmapBySize(String path, int width, int height) {
        BitmapFactory.Options option = new BitmapFactory.Options();
        option.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, option);
        option.inSampleSize = computeSampleSize(option, -1, width * height);

        option.inJustDecodeBounds = false;
        Bitmap bitmap = null;
        try {
            bitmap = BitmapFactory.decodeFile(path, option);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bitmap;
    }

    public static int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {
        int initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels);
        int roundedSize;
        if (initialSize <= 8) {
            roundedSize = 1;
            while (roundedSize < initialSize) {
                roundedSize <<= 1;
            }
        } else {
            roundedSize = (initialSize + 7) / 8 * 8;
        }
        return roundedSize;
    }

    private static int computeInitialSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {
        double w = options.outWidth;
        double h = options.outHeight;
        int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
        int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(Math.floor(w / minSideLength), Math.floor(h / minSideLength));
        if (upperBound < lowerBound) {
            // return the larger one when there is no overlapping zone.
            return lowerBound;
        }
        if ((maxNumOfPixels == -1) && (minSideLength == -1)) {
            return 1;
        } else if (minSideLength == -1) {
            return lowerBound;
        } else {
            return upperBound;
        }
    }

    public static String bitmapToBase64(Bitmap bitmap) {

        // 要返回的字符串
        String reslut = null;

        ByteArrayOutputStream baos = null;

        try {

            if (bitmap != null) {

                baos = new ByteArrayOutputStream();
                /**
                 * 压缩只对保存有效果bitmap还是原来的大小
                 */
                bitmap.compress(Bitmap.CompressFormat.JPEG, 30, baos);

                baos.flush();
                baos.close();
                // 转换为字节数组
                byte[] byteArray = baos.toByteArray();

                // 转换为字符串
                reslut = Base64.encodeToString(byteArray, Base64.DEFAULT);
            } else {
                return null;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

            try {
                if (baos != null) {
                    baos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return reslut;

    }

    /**
     *
     * @Title: base64ToBitmap
     * @Description: TODO(base64l转换为Bitmap)
     * @param @param base64String
     * @param @return    设定文件
     * @return Bitmap    返回类型
     * @throws
     */
    public static Bitmap base64ToBitmap(String base64String){

        byte[] decode = Base64.decode(base64String, Base64.DEFAULT);

        Bitmap bitmap = BitmapFactory.decodeByteArray(decode, 0, decode.length);

        return bitmap;
    }

//    采样压缩
    public static Bitmap sampleCompression(String path){
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 4;
        Bitmap bm = BitmapFactory.decodeFile(path, options);

        Log.i("wechat", "压缩后图片的大小" + (bm.getByteCount() / 1024 / 1024)
                + "M宽度为" + bm.getWidth() + "高度为" + bm.getHeight());

        return bm;
    }
    /**
     * 将图片转换成Base64编码的字符串
     */
    public static String imageToBase64(String path){
        if(TextUtils.isEmpty(path)){
            return null;
        }
        InputStream is = null;
        byte[] data = null;
        String result = null;
        try{
            is = new FileInputStream(path);
            //创建一个字符流大小的数组。
            data = new byte[is.available()];
            //写入数组
            is.read(data);
            //用默认的编码格式进行编码
            result = Base64.encodeToString(data, Base64.DEFAULT);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(null !=is){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
        return result;
    }
}
